openpyxl获取单元格的主题色的颜色值

您所在的位置:网站首页 沙特王储 萨勒曼 openpyxl获取单元格的主题色的颜色值

openpyxl获取单元格的主题色的颜色值

2024-04-04 12:17| 来源: 网络整理| 查看: 265

📢作者: 小小明-代码实体

📢博客主页:https://blog.csdn.net/as604049322

📢欢迎点赞 👍 收藏 ⭐留言 📝 欢迎讨论!

openpyxl 支持以下几种颜色类型:

RGB (Red, Green, Blue): 这是最常用的颜色类型,允许通过指定红、绿、蓝三原色的组合来自定义颜色。RGB值通常以十六进制格式表示。Theme: Excel有一套主题颜色,可以通过指定主题颜色的索引来使用这些颜色。Indexed: 这是Excel早期版本中使用的一种颜色系统,它通过索引号来引用一组预定义的颜色。

对于RGB类型的颜色直接使用cell.fill.start_color.rgb即可获取其颜色,但是对于Theme类型的单元格获取颜色却返回一个错误。

这是因为主题色会随着主题的变化而变化,如下图:

image-20231117200205613

可以看到每个主题有10个基础色,然后受到透明度的影响,我将第一个单元格设置了上图的主题色。

我们创建Excel文件进行测试:

from openpyxl import load_workbook wb = load_workbook("color_test.xlsx") wbs = wb.active cell = wbs.cell(1, 1) cell.fill.start_color Parameters: rgb=None, indexed=None, auto=None, theme=5, tint=0.4, type='theme'

可以看到这就是一个theme类型的颜色,确实是索引5的位置,透明度40%。

我们尝试获取rgb颜色:

cell.fill.start_color.rgb

会返回Values must be of type 这样一个带有错误信息的字符串。

当然也可以调用index属性自动获取rgb或者在主题色中的索引:

cell.fill.start_color.index 5

如果是一个RGB 类型的颜色:

cell = wbs.cell(1, 3) cell.fill.start_color Parameters: rgb='FFF4B382', indexed=None, auto=None, theme=None, tint=0.0, type='rgb'

此时调用index或rgb属性都可以获取rgb颜色值。

那么我们如何获取主题色对应的RGB颜色呢?这个openpyxl并没有提供一个直接的方式,我们只能自己做xml解析了。下面我封装了一个工具类:

from colorsys import rgb_to_hls, hls_to_rgb class ThemeColorConverter: RGBMAX = 0xff HLSMAX = 240 def __init__(self, wb): self.colors = self.get_theme_colors(wb) @staticmethod def tint_luminance(tint, lum): if tint 6: red = red[-6:] # Ignore preceding '#' and alpha values rgbmax = ThemeColorConverter.RGBMAX blue = int(red[4:], 16) / rgbmax green = int(red[2:4], 16) / rgbmax red = int(red[0:2], 16) / rgbmax else: red, green, blue = red h, l, s = rgb_to_hls(red, green, blue) hlsmax = ThemeColorConverter.HLSMAX return (int(round(h * hlsmax)), int(round(l * hlsmax)), int(round(s * hlsmax))) @staticmethod def get_theme_colors(wb): from openpyxl.xml.functions import QName, fromstring xlmns = 'http://schemas.openxmlformats.org/drawingml/2006/main' root = fromstring(wb.loaded_theme) themeEl = root.find(QName(xlmns, 'themeElements').text) colorSchemes = themeEl.findall(QName(xlmns, 'clrScheme').text) firstColorScheme = colorSchemes[0] colors = [] for c in ['lt1', 'dk1', 'lt2', 'dk2', 'accent1', 'accent2', 'accent3', 'accent4', 'accent5', 'accent6']: accent = firstColorScheme.find(QName(xlmns, c).text) for i in list(accent): if 'window' in i.attrib['val']: colors.append(i.attrib['lastClr']) else: colors.append(i.attrib['val']) return colors def theme_and_tint_to_rgb(self, theme, tint): rgb = self.colors[theme] h, l, s = self.rgb_to_ms_hls(rgb) return self.rgb_to_hex(self.ms_hls_to_rgb(h, self.tint_luminance(tint, l), s))

具体如何xml解析可以看上面的get_theme_colors函数。

下面我们获取一下当前Excel选中主题的10个基础色调:

theme_color = ThemeColorConverter(wb) print(theme_color.colors) ['FFFFFF', '000000', 'E7E6E6', '44546A', '4874CB', 'EE822F', 'F2BA02', '75BD42', '30C0B4', 'E54C5E']

然后我们传入索引和透明度获取颜色:

theme_color.theme_and_tint_to_rgb(5, 0.4) 'F4B281'

但使用取色工具测量第一个单元格的颜色值为#f4b382,有微量误差,这属于正常现象,也完全不会影响视觉。这是因为hls+透明度转rgb颜色的过程中存在小数运算,四舍五入后就会造成一定误差。

人眼对低位数据变化不敏感

image-20231117204721115

在24位位图中高8位构成蓝色通道,中8位构成绿色通道,低8位构成红色通道。经测试,在删除各通道的低4位数据并加入随机噪音后,图片用肉眼无法观察到任何变化。现在展示一张图片在删除各通道的低位数据,并加入随机噪音后图片的变化。

image-20231117201646876

可以看到在每个通道低三位的数据进行随意修改,肉眼几乎看不出变化。低三位,意味着7以内的变化都不会有影响。

最后我们封装一个可以查看任何单元格颜色的函数:

from openpyxl.styles.colors import COLOR_INDEX def get_cell_color(cell): color = cell.fill.start_color if color.type == "rgb": return color.rgb elif color.type == "indexed": color_index = color.indexed if color_index is None or color_index


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3